package com.spzx.product.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.core.utils.StringUtils;
import com.spzx.product.api.domain.vo.SkuLockVo;
import com.spzx.product.domain.SkuStock;
import com.spzx.product.mapper.SkuStockMapper;
import com.spzx.product.service.SkuStockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 商品sku库存表 服务实现类
 * </p>
 *
 * @author atguigu
 * @since 2024-10-26
 */
@Service
public class SkuStockServiceImpl extends ServiceImpl<SkuStockMapper, SkuStock> implements SkuStockService {



    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public String checkAndLockStock(String tradeNo, List<SkuLockVo> skuLockVoList) {
        StringBuilder stringBuilder = new StringBuilder();
        //遍历
        skuLockVoList.forEach(skuLockVo -> {
            SkuStock skuStock =baseMapper.checkStock(skuLockVo.getSkuId(),skuLockVo.getSkuNum());
            if (skuStock!=null){
                //有库存
                skuLockVo.setHaveStock(true);
            }else {
                skuLockVo.setHaveStock(false);
                stringBuilder.append(skuLockVo.getSkuName()).append("库存不足\n");
            }
        });
            if (StringUtils.hasText(stringBuilder.toString())){
                return stringBuilder.toString();
            }

        //锁库存
        skuLockVoList.forEach(skuLockVo -> {
          //锁库存
            baseMapper.lockStock(skuLockVo.getSkuId(),skuLockVo.getSkuNum());
        });

            //将锁定的库存的数据放在Redis中
        String redisKey="sku:lock:"+tradeNo;
        redisTemplate.opsForValue().set(redisKey,skuLockVoList,1, TimeUnit.MINUTES);
        return null;
    }

    //减少库存加上销量
    @Override
    public void minusStockAddSales(String orderNo) {
        //从Redis中获取锁定的库存
        List<SkuLockVo> skuLockVoList = (List<SkuLockVo>) redisTemplate.opsForValue().get("sku:lock:" + orderNo);
        //遍历
        if (!CollectionUtils.isEmpty(skuLockVoList)){
            skuLockVoList.forEach(skuLockVo -> {
                //调用basemapper中减少库存增加销量的方法
                baseMapper.minusStockAddSales(skuLockVo.getSkuId(),skuLockVo.getSkuNum());
            });
        }
        //删除Redis中缓存的锁定库存的数据
        redisTemplate.delete("sku:lock:" + orderNo);

    }

    @Override
    public void unLockStocl(String trodeNo) {
        //做幂等性操作,防止重复提交
        String flagKey="sku:unlock:"+trodeNo;
        //向Redis中存放数据
        Boolean flag = redisTemplate.opsForValue().setIfAbsent(flagKey, trodeNo,1,TimeUnit.HOURS);
        if (!flag){
            //重复提交
            throw new ServiceException("请勿重复取消订单(解锁库存)");
        }
        //向Redis中获取锁定库存的key
        String redisLockStockKey ="sku:lock:"+trodeNo;
        //从Redis中获取锁定的库存
        List<SkuLockVo> skuLockVoList = (List<SkuLockVo>) redisTemplate.opsForValue().get(redisLockStockKey);
        //验空
        if (!CollectionUtils.isEmpty(skuLockVoList)){
            //遍历
            skuLockVoList.forEach(skuLockVo -> {
                //掉用baseMapper中解锁库存的方法
                baseMapper.unLockStock(skuLockVo.getSkuId(),skuLockVo.getSkuNum());
            });
        }
        //将Redis中存储的锁定库存的数据删除
        redisTemplate.delete(redisLockStockKey);
    }
}
